package com.km.algorithm

import com.km.algorithm.FPvalue.probF

/**
  * Created by liuwei on 2017/5/25.
  */
object ChisqTest {

  def probChi( Chisqnorm: Double,  N1: Int):Double= {

    var p = 0.0
    val AM = 1.7E-38
    val WU2P = 2.5066282746310005
    var pr = 0.0
    var z = 0.0
    var SU = 0.0
    var J = 0
    if (Chisqnorm == 0) return 1

    val EC = Math.exp(-Chisqnorm / 2)
    // IF ED<AM GOTO 1200
    N1 match {
      case 1 =>
        z = Math.sqrt(Chisqnorm)
        pr = 1 - zProb(z)
        p = 2 * pr
        return p
      case 2 =>
        p = EC
        return p
      case _ =>
    }


    val CX = Math.sqrt(Chisqnorm)
    val ZC = 1.0 / WU2P * EC

    var IE = 0
    var I1 = 0.0
    var RD = 0.0
    if (N1 % 2 == 0) {
      IE = 1
      SU = ZC
      I1 = (N1 - 2) / 2
      RD = ZC
    }
    else {
      IE = 0
      SU = 0
      I1 = (N1 - 1) / 2
      RD = ZC / CX
    }
    if (RD >= AM && N1 <= 500) { //if ( N1<=500) {
      z = CX
      pr = 1 - zProb(z)
      if (IE == 1) J = 2
      else J = 1
      var i = 1
      while ( {
        i <= I1
      }) {
        RD = RD * Chisqnorm / J
        J += 2
        SU += RD

        {
          i += 1; i - 1
        }
      }
      if (IE == 1) p = WU2P * SU
      else p = 2 * (pr + SU)
    }
    else {
      val z0 = Math.pow(Chisqnorm / N1, 0.333333333333333333) - 1.0 + 2.0 / (9.0 * N1)
      z = z0 * Math.sqrt(9.0 * N1 / 2.0)
      p = 1 - zProb(z)
    }
    p
  }


  var flag = false
  def zProb (z:Double):Double={

    if (z < -7) return 0.0
    if (z > 7) return 1.0


    if (z < 0.0) flag = true
    else flag = false

    val zz = Math.abs(z)
    var b = 0.0
    val s = Math.sqrt(2) / 3 * zz
    var  HH = .5
    var i = 0
    while ( {
      i < 12
    }) {
      val a = Math.exp(-HH * HH / 9) * Math.sin(HH * s) / HH
      b = b + a
      HH = HH + 1.0

      {
        i += 1; i - 1
      }
    }
   var p =.5 - b / Math.PI
    //p=b/Math.PI;
    if (!flag) p = 1.0 - p

    p
  }


  def main(args: Array[String]): Unit = {
    println(probChi( 16.35968482 ,6));
  }

}
